package cn.workreport.modules.organization.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.workreport.modules.common.enums.IsEnum;
import cn.workreport.modules.common.exception.ServiceException;
import cn.workreport.modules.common.vo.PageVO;
import cn.workreport.modules.group.entity.Group;
import cn.workreport.modules.group.service.IGroupService;
import cn.workreport.modules.organization.entity.Organization;
import cn.workreport.modules.organization.enums.OrgStatusEnum;
import cn.workreport.modules.organization.mapper.OrganizationMapper;
import cn.workreport.modules.organization.service.IOrganizationService;
import cn.workreport.modules.role.entity.Role;
import cn.workreport.modules.role.service.IRoleService;
import cn.workreport.modules.users.entity.UserEntity;
import cn.workreport.modules.users.entity.UserExtends;
import cn.workreport.modules.users.service.IUserService;
import cn.workreport.util.EnumUtil;
import cn.workreport.util.InitData;
import cn.workreport.util.JsonResult;
import cn.workreport.util.UserChacheFromToken;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 机构 业务接口实现类
 * </p>
 *
 * @author yyf
 * @since 2022-03-24
 */
@Slf4j
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements IOrganizationService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IGroupService groupService;

    @Autowired
    private InitData initData;

    @Override
    public void wrapEntity(Organization entity) {
        if (entity == null) {
            return;
        }
        // 【机构状态】中文
        if (!ObjectUtils.isEmpty(entity.getOrgStatus())) {
            String orgStatusLabel = entity.getOrgStatus().getLabel();
            entity.setOrgStatusLabel(orgStatusLabel);
        }
        // 【是否可加入】中文
        if (!ObjectUtils.isEmpty(entity.getCanJoin())) {
            String canJoinLabel = entity.getCanJoin().getLabel();
            entity.setCanJoinLabel(canJoinLabel);
        }
        // 查询管理员用户名
        if (!ObjectUtil.isEmpty(entity.getOrgManagerId())) {
            UserEntity manager = userService.getById(entity.getOrgManagerId());
            if (!ObjectUtil.isEmpty(manager)) {
                entity.setOrgManagerName(manager.getUsername());
            }
        }
        // 查询机构人员数量
        Integer memberCount = this.userService.countMemberByOrgId(entity.getId());
        entity.setMemberCount(memberCount);
        // 如果不是机构管理员，不返回重要数据
        if (!UserChacheFromToken.getUserId().equals(entity.getOrgManagerId())) {
            entity.setVerifyAnswer(null);
        }
    }

    @Override
    public PageVO<Organization> pageEntity(IPage<Organization> page, Wrapper<Organization> queryWrapper) {
        IPage<Organization> pageResult = this.page(page, queryWrapper);
        return new PageVO<>(pageResult);
    }

    @Override
    public Organization getByIdEntity(Integer id) {
        Organization entity = this.getById(id);
        this.wrapEntity(entity);
        return entity;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult<?> saveOrUpdateEntity(Organization entity) {
        String orgName = entity.getOrgName();
        // 去掉前后空格
        orgName = StrUtil.trim(orgName);
        if (StrUtil.isBlank(orgName)) {
            return JsonResult.fail("机构名称不能为空！");
        }
        entity.setOrgName(orgName);
        // 是否是新增
        boolean isCreate = ObjectUtil.isEmpty(entity.getId());
        // 检查名称不能重复
        Organization hasEntity = getEntityByOrgName(orgName);
        if (!ObjectUtils.isEmpty(hasEntity)) {
            // 如果是新增
            if (isCreate) {
                return JsonResult.fail("该机构名称已经存在，不能重复创建");
            }
            // 如果是修改
            else if (!hasEntity.getId().equals(entity.getId())) {
                return JsonResult.fail("该机构名称已经存在，请重新修改");
            }
        }
        // 如果是新增
        if (isCreate) {
            // 如果当前登录用户不是超级管理员，并且已经绑定了机构，则不能进行创建
            UserEntity loginUser = UserChacheFromToken.getUser();
            if (
                    (ObjectUtil.isEmpty(loginUser.getIsSupperAdmin()) || !loginUser.getIsSupperAdmin())
                            && !ObjectUtil.isEmpty(loginUser.getOrgId())
            ) {
                return JsonResult.fail("您已经关联过了机构，不能进行创建");
            }
            // 如果没有传管理员id
            if (ObjectUtil.isEmpty(entity.getOrgManagerId())) {
                // 如果当前用户没绑定机构
                if (!ObjectUtil.isEmpty(loginUser.getOrgId())) {
                    return JsonResult.fail("您已经关联了机构，不能进行创建");
                }
                // 默认【机构管理员】是当前用户
                entity.setOrgManagerId(loginUser.getId());
            } else {
                // 查询此人有没有绑定过机构
                UserEntity manager = userService.getById(entity.getOrgManagerId());
                if (ObjectUtil.isEmpty(manager)) {
                    return JsonResult.fail("该用户不存在");
                }
                if (!ObjectUtil.isEmpty(manager.getOrgId())) {
                    return JsonResult.fail("该用户已经关联了机构，不能进行创建");
                }
            }
            // 默认【状态】为启用
            entity.setOrgStatus(OrgStatusEnum.ENABLE);
            // 如果没传【是否可加入】字段，默认为“是”
            if (ObjectUtil.isEmpty(entity.getCanJoin())) {
                entity.setCanJoin(IsEnum.YES);
            }
        }
        // 修改机构
        else {
            Organization organization = getById(entity.getId());
            // 如果机构停用则无法设置
            if (OrgStatusEnum.DISABLED == organization.getOrgStatus()) {
                return JsonResult.fail("该机构已经暂停使用");
            }
        }
        // 如果开启了验证，则验证问题和答案必传
        if (IsEnum.YES == entity.getIsOpenVerification()) {
            if (ObjectUtil.isEmpty(entity.getVerifyQuestion())) {
                return JsonResult.fail("请填写验证问题");
            }
            if (ObjectUtil.isEmpty(entity.getVerifyAnswer())) {
                return JsonResult.fail("请填写验证答案");
            }
        }
        // 执行数据保存或修改
        if (!this.saveOrUpdate(entity)) {
            throw new ServiceException("保存数据失败");
        }
        // 如果创建了新的结构，需要初始化该机构的角色-拿到机构的id
        if (isCreate && ObjectUtil.isNotEmpty(entity.getId())) {
            List<Role> roleList = initData.getInitRoleList(entity.getId());
            log.info("初始化该机构的角色 ==> roleList" + roleList);
            if (!ObjectUtil.isEmpty(roleList)) {
                if (!this.roleService.saveBatch(roleList)) {
                    throw new ServiceException("初始化机构角色数据失败");
                }
            }
        }
        this.wrapEntity(entity);
        return JsonResult.ok(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult<?> removeByIdEntity(Integer id) {
        // 查询出关联该机构的人员列表
        List<UserEntity> userList = this.userService.listByOrgId(id);
        if (ObjectUtil.isNotEmpty(userList)) {
            for (UserEntity userEntity : userList) {
                // 清空机构
                userEntity.setOrgId(null);
                // 清空角色
                userEntity.setRoleId(null);
                // 清空是否是组长
                userEntity.setIsLeader(false);
            }
            if (!this.userService.updateBatchById(userList)) {
                throw new ServiceException("清空用户机构数据失败");
            }
        }

        // 删除对应机构的角色
        List<Role> roleList = this.roleService.listByOrgId(id);
        if (ObjectUtil.isNotEmpty(roleList)) {
            Set<Integer> roleIds = roleList.stream().map(Role::getId).collect(Collectors.toSet());
            if (!this.roleService.removeByIds(roleIds)) {
                throw new ServiceException("删除对应机构的角色数据失败");
            }
        }

        // 删除对应机构的组织
        List<Group> groupList = this.groupService.listGroupByOrgId(id);
        if (ObjectUtil.isNotEmpty(groupList)) {
            Set<Integer> groupIds = groupList.stream().map(Group::getId).collect(Collectors.toSet());
            if (!this.groupService.removeByIds(groupIds)) {
                throw new ServiceException("删除对应机构的组织数据失败");
            }
        }

        // 执行删除机构
        boolean isSuccess = super.removeById(id);
        if (!isSuccess) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdsEntity(List<Integer> ids) {
        for (Integer id : ids) {
            JsonResult<?> jsonResult = removeByIdEntity(id);
            if (!jsonResult.getState().equals(JsonResult.SUCCESS)) {
                return JsonResult.fail();
            }
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> preparedData() {
        Map<String, Object> data = new HashMap<>();
        // 机构状态
        List<Map<String, Object>> orgStatusSelectList = EnumUtil.getSelectList(OrgStatusEnum.class);
        data.put("orgStatusSelectList", orgStatusSelectList);
        // 是否可加入
        List<Map<String, Object>> canJoinSelectList = EnumUtil.getSelectList(IsEnum.class);
        data.put("canJoinSelectList", canJoinSelectList);
        // 是否开启验证
        List<Map<String, Object>> isOpenVerificationSelectList = EnumUtil.getSelectList(IsEnum.class);
        data.put("isOpenVerificationSelectList", isOpenVerificationSelectList);
        return JsonResult.ok(data);
    }

    @Override
    public JsonResult<?> setStatus(Integer id, OrgStatusEnum status) {
        Organization organization = getById(id);
        if (ObjectUtils.isEmpty(organization)) {
            return JsonResult.fail("该条数据不存在");
        }
        organization.setOrgStatus(status);
        boolean isSuccess = super.saveOrUpdate(organization);
        if (!isSuccess) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> setCanJoin(Integer orgId, IsEnum canJoin) {
        Organization organization = getById(orgId);
        if (ObjectUtils.isEmpty(organization)) {
            return JsonResult.fail("该条数据不存在");
        }
        // 如果机构停用则无法设置
        if (OrgStatusEnum.DISABLED == organization.getOrgStatus()) {
            return JsonResult.fail("该机构已经暂停使用");
        }
        organization.setCanJoin(canJoin);
        boolean isSuccess = saveOrUpdate(organization);
        if (!isSuccess) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    public Organization getEntityByOrgName(String orgName) {
        if (StrUtil.isBlank(orgName)) {
            return null;
        }
        LambdaQueryWrapper<Organization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Organization::getOrgName, orgName);
        return getOne(wrapper);
    }
}

